package com.xdog.okx.controller;

import com.xdog.common.core.domain.R;
import com.xdog.okx.service.IWeb3jService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import org.web3j.protocol.core.methods.response.*;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

/**
 * Web3j控制器
 * 提供基于Web3j的区块链数据查询接口
 *
 * 该控制器通过Web3j库直接与区块链节点通信，提供基础的区块链数据查询功能，
 * 包括区块信息、交易信息、地址余额等查询接口。
 */
@RestController
@RequestMapping("/web3j")
public class Web3jController {

    @Resource
    private IWeb3jService web3jService;

    /**
     * 获取指定区块号的区块详情
     *
     * 通过区块编号查询区块的详细信息，包括区块头、交易列表等数据。
     *
     * @param blockNumber 区块编号（BigInteger类型）
     * @return EthBlock 区块信息对象，包含区块头和交易列表等详细信息
     */
    @GetMapping("/block/{blockNumber}")
    public R<EthBlock> getBlockByNumber(@PathVariable BigInteger blockNumber) {
        try {
            EthBlock block = web3jService.getBlockByNumber(blockNumber);
            return R.ok(block);
        } catch (Exception e) {
            return R.fail("获取区块详情失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定交易哈希的交易详情
     *
     * 通过交易哈希查询交易的详细信息，包括发送方、接收方、交易金额等数据。
     *
     * @param transactionHash 交易哈希（String类型）
     * @return EthTransaction 交易信息对象，包含交易的详细信息
     */
    @GetMapping("/transaction/{transactionHash}")
    public R<EthTransaction> getTransactionByHash(@PathVariable String transactionHash) {
        try {
            EthTransaction transaction = web3jService.getTransactionByHash(transactionHash);
            return R.ok(transaction);
        } catch (Exception e) {
            return R.fail("获取交易详情失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定地址的余额
     *
     * 查询指定地址在最新区块中的余额信息。
     *
     * @param address 区块链地址（String类型）
     * @return EthGetBalance 余额信息对象，包含地址的余额（以wei为单位）
     */
    @GetMapping("/balance/{address}")
    public R<EthGetBalance> getBalance(@PathVariable String address) {
        try {
            EthGetBalance balance = web3jService.getBalance(address);
            return R.ok(balance);
        } catch (Exception e) {
            return R.fail("获取地址余额失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定区块的交易数量
     *
     * 查询指定区块中包含的交易数量。
     *
     * @param blockNumber 区块编号（BigInteger类型）
     * @return EthGetTransactionCount 交易数量信息对象
     */
    @GetMapping("/block-transaction-count/{blockNumber}")
    public R<EthGetBlockTransactionCountByNumber> getTransactionCountByBlockNumber(@PathVariable BigInteger blockNumber) {
        try {
            EthGetBlockTransactionCountByNumber transactionCount = web3jService.getTransactionCountByBlockNumber(blockNumber);
            return R.ok(transactionCount);
        } catch (Exception e) {
            return R.fail("获取区块交易数量失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定地址的交易数量
     *
     * 查询指定地址发送的交易数量（nonce值）。
     *
     * @param address 区块链地址（String类型）
     * @return EthGetTransactionCount 交易数量信息对象（nonce值）
     */
    @GetMapping("/address-transaction-count/{address}")
    public R<EthGetTransactionCount> getTransactionCountByAddress(@PathVariable String address) {
        try {
            EthGetTransactionCount transactionCount = web3jService.getTransactionCountByAddress(address);
            return R.ok(transactionCount);
        } catch (Exception e) {
            return R.fail("获取地址交易数量失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取指定代币地址的代币详细信息
     *
     * 通过与ERC20代币合约交互，获取代币的基本信息，包括名称、符号和小数位数。
     *
     * @param tokenAddress 代币合约地址（String类型）
     * @return Map 代币信息Map，包含name、symbol、decimals等字段
     */
    @GetMapping("/token/{tokenAddress}")
    public R<Map<String, Object>> getTokenInfo(@PathVariable String tokenAddress) {
        try {
            String name = web3jService.getTokenName(tokenAddress);
            String symbol = web3jService.getTokenSymbol(tokenAddress);
            BigInteger decimals = web3jService.getTokenDecimals(tokenAddress);
            
            Map<String, Object> tokenInfo = new HashMap<>();
            tokenInfo.put("name", name);
            tokenInfo.put("symbol", symbol);
            tokenInfo.put("decimals", decimals);
            
            return R.ok(tokenInfo);
        } catch (Exception e) {
            return R.fail("获取代币信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取指定代币地址的完整代币信息
     *
     * 通过与ERC20代币合约交互，获取代币的完整信息，包括名称、符号、小数位数、总供应量等。
     *
     * @param tokenAddress 代币合约地址（String类型）
     * @return Map 代币完整信息Map
     */
    @GetMapping("/token-full/{tokenAddress}")
    public R<Map<String, Object>> getTokenFullInfo(@PathVariable String tokenAddress) {
        try {
            Map<String, Object> tokenInfo = web3jService.getTokenFullInfo(tokenAddress);
            return R.ok(tokenInfo);
        } catch (Exception e) {
            return R.fail("获取代币完整信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取指定地址的代币余额
     *
     * 通过与ERC20代币合约交互，获取指定地址的代币余额。
     *
     * @param tokenAddress 代币合约地址（String类型）
     * @param address 用户地址（String类型）
     * @return BigInteger 代币余额
     */
    @GetMapping("/token-balance/{tokenAddress}/{address}")
    public R<BigInteger> getTokenBalance(@PathVariable String tokenAddress, @PathVariable String address) {
        try {
            BigInteger balance = web3jService.getTokenBalance(tokenAddress, address);
            return R.ok(balance);
        } catch (Exception e) {
            return R.fail("获取代币余额失败: " + e.getMessage());
        }
    }
}